#ifndef PCB_DETECTION_CONTEXT_H
#define PCB_DETECTION_CONTEXT_H

#include <iostream>
#include <bitset>
#include <mutex>
#include <string>
#include <atomic>
#include "mqttProtocol.h"



// 设备状态枚举
enum class DeviceStatus {
    STOPPED,   // 停止
    RUNNING,   // 运行
    PAUSED     // 暂停
};

// 架子和槽位信息结构（纯数据）
struct RackSlotInfo {
    int rackId;      // 架子编号
    int slotId;      // 槽位编号
    bool isValid;    // 是否有效（false表示无可用空间）
};

struct ProductInfo {
    std::string model;
    std::string batch;
    std::string serial;  // 自动递增的序列号
};

class PCBDetectionContext {
private:
    // 单例实例
    static PCBDetectionContext* instance;
    static std::mutex mtx;
    
    // 1. 开启检测的缺陷类型（8种）
    std::bitset<8> enabledDefects;
    
    // 3. 已放置PCB的架子信息（纯数据结构）
    struct RackInfo {
        int rackId;                // 架子编号
        std::bitset<16> slots;     // 槽位使用情况，1表示已占用
        int occupiedCount;         // 已占用槽位数
    };
    
    // 当前使用的架子（好的和坏的各一个）
    RackInfo currentGoodRack;
    RackInfo currentBadRack;
    
    // 4. 设备状态
    std::atomic<DeviceStatus> deviceStatus;
    
    struct {
        std::string model;                    // Product model
        std::string batch;                    // Batch number
        std::atomic<int> serialCounter;       // 序列号计数器
        std::string serial;                   // Serial number
    } productInfo;                            // Product information
    // 私有构造函数，防止外部实例化
    PCBDetectionContext();
    
    // 禁止拷贝构造和赋值运算符
    PCBDetectionContext(const PCBDetectionContext&) = delete;
    PCBDetectionContext& operator=(const PCBDetectionContext&) = delete;

    // 辅助方法（私有）
    bool isRackFull(const RackInfo& rack) const;
    int findEmptySlot(const RackInfo& rack) const;

public:
    // 获取单例实例
    static PCBDetectionContext* getInstance();
    
    // 释放单例实例（可选，用于程序结束时）
    static void releaseInstance();
    
    // 1. 缺陷类型管理方法
    void enableDefect(DefectType type);
    void disableDefect(DefectType type);
    bool isDefectEnabled(DefectType type) const;
    std::string getEnabledDefects() const;
    
    // 3. 架子和槽位管理方法
    /**
     * 获取可存放好PCB的架子和槽位信息，并尝试放置PCB
     * @param placePCB 是否尝试放置PCB
     * @return 包含架子ID、槽位ID和操作结果的结构
     */
    RackSlotInfo getAvailableGoodRackSlot(bool placePCB = false);
    
    /**
     * 获取可存放坏PCB的架子和槽位信息，并尝试放置PCB
     * @param placePCB 是否尝试放置PCB
     * @return 包含架子ID、槽位ID和操作结果的结构
     */
    RackSlotInfo getAvailableBadRackSlot(bool placePCB = false);
    
    /**
     * 重置（清空）好PCB架子
     */
    void resetGoodRack();
    
    /**
     * 重置（清空）坏PCB架子
     */
    void resetBadRack();
    
    /**
     * 获取好PCB架子的状态信息
     * @return 架子状态的字符串描述
     */
    std::string getGoodRackStatus() const;
    
    /**
     * 获取坏PCB架子的状态信息
     * @return 架子状态的字符串描述
     */
    std::string getBadRackStatus() const;
    
    // 4. 设备状态管理方法
    void setDeviceStatus(DeviceStatus status);
    DeviceStatus getDeviceStatus() const;
    std::string getDeviceStatusString() const;
    
    // 打印当前上下文状态
    void printStatus() const;

    // 在PCBDetectionContext类的public部分添加
    /**
    * 从控制消息更新上下文状态
    * @param message 控制消息
    */
    void updateFromControlMessage(const ControlMessage& message);

   // ProductInfo productInfo;
    ProductInfo getProductInfo();
};

#endif // PCB_DETECTION_CONTEXT_H